/*
 * PhoneGap is available under *either* the terms of the modified BSD license *or* the
 * MIT License (2008). See http://opensource.org/licenses/alphabetical for full text.
 * 
 * Copyright (c) 2005-2010, Nitobi Software Inc.
 * Copyright (c) 2010-2011, IBM Corporation
 */
package com.phonegap.extensions;


import org.json.JSONArray;
import org.json.JSONException;
import android.app.AlertDialog;
import android.widget.EditText;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.Color;
import android.media.AudioManager;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.webkit.JsResult;
import android.webkit.WebChromeClient;
import android.webkit.JsPromptResult;
import android.webkit.WebSettings;
import android.webkit.WebStorage;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.webkit.GeolocationPermissions.Callback;
import android.webkit.WebSettings.LayoutAlgorithm;
import android.widget.LinearLayout;

import com.phonegap.DroidGap.GapViewClient;
import com.phonegap.api.Plugin;
import com.phonegap.api.PluginManager;
import com.phonegap.*;


public class DroidGap extends com.phonegap.DroidGap {

	
	// The initial URL for our app
	private String url;
	
	// The base of the initial URL for our app
	private String baseUrl;

	
	// Flag indicates that a loadUrl timeout occurred
	private int loadUrlTimeout = 0;
	
	public void init() {
		super.init();
		this.setWebViewClient(this.appView, new com.phonegap.extensions.DroidGap.GapViewClient(this));
		
	}
    
            
	/**
	 * Look at activity parameters and process them.
	 * This must be called from the main UI thread.
	 */
	private void handleActivityParameters() {

		// Init web view if not already done
		if (this.appView == null) {
			this.init();
		}

		// If spashscreen
		this.splashscreen = this.getIntegerProperty("splashscreen", 0);
		if (this.splashscreen != 0) {
			root.setBackgroundResource(this.splashscreen);
		}

		// If hideLoadingDialogOnPageLoad
		this.hideLoadingDialogOnPageLoad = this.getBooleanProperty("hideLoadingDialogOnPageLoad", false);

		// If loadInWebView
		this.loadInWebView = this.getBooleanProperty("loadInWebView", false);

		// If loadUrlTimeoutValue
		int timeout = this.getIntegerProperty("loadUrlTimeoutValue", 0);
		if (timeout > 0) {
			this.loadUrlTimeoutValue = timeout;
		}
		
		// If keepRunning
		this.keepRunning = this.getBooleanProperty("keepRunning", true);
	}
	
    /**
     * Load the url into the webview.
     * 
     * @param url
     */
	public void loadUrl(final String url) {
		System.out.println("loadUrl("+url+")");
		this.url = url;
		int i = url.lastIndexOf('/');
		if (i > 0) {
			this.baseUrl = url.substring(0, i);
		}
		else {
			this.baseUrl = this.url;
		}
		System.out.println("url="+url+" baseUrl="+baseUrl);

		// Load URL on UI thread
		final DroidGap me = this;
		this.runOnUiThread(new Runnable() {
			public void run() {

				// Handle activity parameters
				me.handleActivityParameters();

				// Initialize callback server
				me.callbackServer.init(url);

				// If loadingDialog, then show the App loading dialog
				String loading = me.getStringProperty("loadingDialog", null);
				if (loading != null) {

					String title = "";
					String message = "Loading Application...";

					if (loading.length() > 0) {
						int comma = loading.indexOf(',');
						if (comma > 0) {
							title = loading.substring(0, comma);
							message = loading.substring(comma+1);
						}
						else {
							title = "";
							message = loading;
						}
					}
					JSONArray parm = new JSONArray();
					parm.put(title);
					parm.put(message);
					me.pluginManager.exec("Notification", "activityStart", null, parm.toString(), false);
				}

				// Create a timeout timer for loadUrl
				final int currentLoadUrlTimeout = me.loadUrlTimeout;
				Runnable runnable = new Runnable() {
					public void run() {
						try {
							synchronized(this) {
								wait(me.loadUrlTimeoutValue);
							}
						} catch (InterruptedException e) {
							e.printStackTrace();
						}		

						// If timeout, then stop loading and handle error
						if (me.loadUrlTimeout == currentLoadUrlTimeout) {
							me.appView.stopLoading();
							me.webViewClient.onReceivedError(me.appView, -6, "The connection to the server was unsuccessful.", url);
						}
					}
				};
				Thread thread = new Thread(runnable);
				thread.start();
				
				
				if(com.phonegap.extensions.PreProcessor.getInstance(appView).shouldMakePreProcess(url)) {
					com.phonegap.extensions.PreProcessor.getInstance(appView).loadUrl(url);
					
				}
				else {
					
					me.appView.loadUrl(url);
				}
				
				
				
				
				
				
			}
		});
	}
	
	
	

	  /**
     * The webview client receives notifications about appView
     */
    public class GapViewClient extends WebViewClient {

        DroidGap ctx;

        /**
         * Constructor.
         * 
         * @param ctx
         */
        public GapViewClient(DroidGap ctx) {
            this.ctx = ctx;
        }
        
        /**
         * Give the host application a chance to take over the control when a new url 
         * is about to be loaded in the current WebView.
         * 
         * @param view			The WebView that is initiating the callback.
         * @param url			The url to be loaded.
         * @return				true to override, false for default behavior
         */
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
        	// If dialing phone (tel:5551212)
        	if (url.startsWith(WebView.SCHEME_TEL)) {
        		try {
        			Intent intent = new Intent(Intent.ACTION_DIAL);
        			intent.setData(Uri.parse(url));
        			startActivity(intent);
        		} catch (android.content.ActivityNotFoundException e) {
        			System.out.println("Error dialing "+url+": "+ e.toString());
        		}
        		return true;
        	}
        	
        	// If displaying map (geo:0,0?q=address)
        	else if (url.startsWith("geo:")) {
           		try {
        			Intent intent = new Intent(Intent.ACTION_VIEW);
        			intent.setData(Uri.parse(url));
        			startActivity(intent);
        		} catch (android.content.ActivityNotFoundException e) {
        			System.out.println("Error showing map "+url+": "+ e.toString());
        		}
        		return true;        		
        	}
			
        	// If sending email (mailto:abc@corp.com)
        	else if (url.startsWith(WebView.SCHEME_MAILTO)) {
           		try {
        			Intent intent = new Intent(Intent.ACTION_VIEW);
        			intent.setData(Uri.parse(url));
        			startActivity(intent);
        		} catch (android.content.ActivityNotFoundException e) {
        			System.out.println("Error sending email "+url+": "+ e.toString());
        		}
        		return true;        		
        	}
        	
        	// If sms:5551212?body=This is the message
        	else if (url.startsWith("sms:")) {
        		try {
        			Intent intent = new Intent(Intent.ACTION_VIEW);

        			// Get address
        			String address = null;
        			int parmIndex = url.indexOf('?');
        			if (parmIndex == -1) {
        				address = url.substring(4);
        			}
        			else {
        				address = url.substring(4, parmIndex);

        				// If body, then set sms body
        				Uri uri = Uri.parse(url);
        				String query = uri.getQuery();
        				if (query != null) {
        					if (query.startsWith("body=")) {
        						intent.putExtra("sms_body", query.substring(5));
        					}
        				}
        			}
        			intent.setData(Uri.parse("sms:"+address));
        			intent.putExtra("address", address);
        			intent.setType("vnd.android-dir/mms-sms");
        			startActivity(intent);
        		} catch (android.content.ActivityNotFoundException e) {
        			System.out.println("Error sending sms "+url+":"+ e.toString());
        		}
        		return true;
        	}

        	// All else
        	else {

        		int i = url.lastIndexOf('/');
        		String newBaseUrl = url;
        		if (i > 0) {
        			newBaseUrl = url.substring(0, i);
        			ctx.loadUrl(url);
        			
        		}	
        		// If not our application, let default viewer handle
        		else {
        			try {
        				Intent intent = new Intent(Intent.ACTION_VIEW);
        				intent.setData(Uri.parse(url));
        				startActivity(intent);
                	} catch (android.content.ActivityNotFoundException e) {
                		System.out.println("Error loading url "+url+":"+ e.toString());
                	}
        		}
        		return true;
        	}
        }
    	
        /**
         * Notify the host application that a page has finished loading.
         * 
         * @param view			The webview initiating the callback.
         * @param url			The url of the page.
         */
        @Override
        public void onPageFinished(WebView view, String url) {
        	super.onPageFinished(view, url);

        	// Clear timeout flag
        	this.ctx.loadUrlTimeout++;

        	// Try firing the onNativeReady event in JS. If it fails because the JS is
        	// not loaded yet then just set a flag so that the onNativeReady can be fired
        	// from the JS side when the JS gets to that code.
        	if (!url.equals("about:blank")) {
        		appView.loadUrl("javascript:try{ PhoneGap.onNativeReady.fire();}catch(e){_nativeReady = true;}");
        	}

        	// Make app view visible
        	appView.setVisibility(View.VISIBLE);

        	// Stop "app loading" spinner if showing
        	if (this.ctx.hideLoadingDialogOnPageLoad) {
        		this.ctx.hideLoadingDialogOnPageLoad = false;
        		this.ctx.pluginManager.exec("Notification", "activityStop", null, "[]", false);
        	}

    		// Clear history, so that previous screen isn't there when Back button is pressed
    		if (this.ctx.clearHistory) {
    			this.ctx.clearHistory = false;
    			this.ctx.appView.clearHistory();
    		}
    		
    		// Shutdown if blank loaded
    		if (url.equals("about:blank")) {
    			if (this.ctx.callbackServer != null) {
    				this.ctx.callbackServer.destroy();
    			}
    		}
        }
        
        /**
         * Report an error to the host application. These errors are unrecoverable (i.e. the main resource is unavailable). 
         * The errorCode parameter corresponds to one of the ERROR_* constants.
         *
         * @param view 			The WebView that is initiating the callback.
         * @param errorCode 	The error code corresponding to an ERROR_* value.
         * @param description 	A String describing the error.
         * @param failingUrl 	The url that failed to load. 
         */
        @Override
        public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
        	System.out.println("onReceivedError: Error code="+errorCode+" Description="+description+" URL="+failingUrl);

        	// Clear timeout flag
        	this.ctx.loadUrlTimeout++;

       	 	// Stop "app loading" spinner if showing
       	 	this.ctx.pluginManager.exec("Notification", "activityStop", null, "[]", false);

        	// Handle error
        	this.ctx.onReceivedError(errorCode, description, failingUrl);
        }
    }
    
	
       
}
